#include "stdafx.hpp"
#include "ColligerePrefDialog.hpp"
#include "ColligereApp.hpp"
#include "ColligereConfigHandler.hpp"
// For the LanguageClientData
#include "ColligereLanguageSelectionDlg.hpp"

IMPLEMENT_DYNAMIC_CLASS ( col::PreferencesDialog, wxDialog );

col::PreferencesDialog::PreferencesDialog ( wxFrame *pParent )
{
	wxXmlResource::Get()->LoadDialog ( this, pParent, "ID_Dialog_Preferences" );

	wxIcon cfg;
	cfg.CopyFromBitmap ( wxGetApp().GetIcon ( App::IconIndex::Configure ) );
	wxASSERT ( cfg.IsOk() );
	SetIcon ( cfg );

	mpDefaultDbCtrl = XRCCTRL ( *this, "ID_TextCtrl_DefaultDb", wxTextCtrl );
	mpGenSettingsCtrl = XRCCTRL ( *this, "ID_CheckListBox_GenSettings", wxCheckListBox );
	mpDbSyncTypeCtrl = XRCCTRL ( *this, "ID_ComboBox_SyncType", wxComboBox );
	mpDbAutoSaveCtrl = XRCCTRL ( *this, "ID_CheckBox_AutoSaveDb", wxCheckBox );
	mpDbAutoVacuumCtrl = XRCCTRL ( *this, "ID_CheckBox_AutoVacuum", wxCheckBox );
	mpDbCompressionLevelCtrl = XRCCTRL ( *this, "ID_ComboBox_CompressionLevel",
		wxComboBox );

	mpDbSyncTypeCtrl->Append ( _("OFF (Unsecure, Fast)"), new SyncTypeClientData 
		( DatabaseHandlerBase::SyncType::Off ) );
	mpDbSyncTypeCtrl->Append ( _("NORMAL (Secure, Slow)"), new SyncTypeClientData 
		( DatabaseHandlerBase::SyncType::Normal ) );
	mpDbSyncTypeCtrl->Append ( _("FULL (Very Secure, Slowest)"), new SyncTypeClientData 
		( DatabaseHandlerBase::SyncType::Full ) );

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	wxInt32 lang_sel = -1;

	foreach ( Language l, wxGetApp().GetAvailableLanguages() )
	{
		lang_sel = langs->Append ( l.GetDisplayString(), l.GetFlag(), 
			new LanguageClientData ( l.GetLanguage() ) );
	}
	
	ConnectEventHandlers();

	LoadSettings();
}

col::PreferencesDialog::~PreferencesDialog()
{
	SaveControlValues();
}

void col::PreferencesDialog::ConnectEventHandlers()
{
	Bind ( wxEVT_COMMAND_BUTTON_CLICKED,
		&PreferencesDialog::OnButtonOk, XRCID( "wxID_OK" ) );
	Bind ( wxEVT_COMMAND_BUTTON_CLICKED,
		&PreferencesDialog::OnButtonBrowseDefaultDb, XRCID ( "ID_Button_BrowseDefaultDb" ) );
	Bind ( wxEVT_COMMAND_BUTTON_CLICKED,
		&PreferencesDialog::OnButtonResetDefaults, XRCID ( "ID_Button_ResetDefaults" ) );
}

void col::PreferencesDialog::LoadVarToGenSettingCheckListBox ( wxUint32 varId )
{
	ConfigVariable var;
	ConfigHandler::Get().GetVar ( varId, var );
	const wxUint32 idx = mpGenSettingsCtrl->Append ( _(var.GetDescription()) );
	mpGenSettingsCtrl->Check ( idx, ConfigHandler::Get().IsEnabled ( var.GetId() ) );
	mGenSettingsItemData[idx] = var.GetId();
}

void col::PreferencesDialog::LoadSettings()
{
	using namespace std;

	typedef ConfigVariable cv;

	ConfigHandler &cfgh = ConfigHandler::Get();

	// Load the "General" page settings.

	mpGenSettingsCtrl->Clear();

	LoadVarToGenSettingCheckListBox ( cv::AskBeforeApplyingValues );
	LoadVarToGenSettingCheckListBox ( cv::AskBeforeExiting );
	LoadVarToGenSettingCheckListBox ( cv::SaveLayoutOnExit );
	LoadVarToGenSettingCheckListBox ( cv::DumpLogToFileOnExit );
	LoadVarToGenSettingCheckListBox ( cv::ShowToolTips );

	long cur_lang = -1;
	ConfigHandler::Get().GetValue ( ConfigVariable::Language, cur_lang );

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	for ( wxUint32 i = 0; i < langs->GetCount(); ++i )
	{
		const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
			( langs->GetClientObject (i) );

		if ( lang_data->GetLanguage() == cur_lang ) 
		{
			langs->SetSelection(i);
			break;
		}
	}

	// Load the "Database" page settings.

	long sync_type = -1;
	cfgh.GetValue ( cv::DatabaseSyncType, sync_type );
	wxASSERT ( sync_type != -1 );

	for ( wxUint32 sync_it = 0; sync_it < mpDbSyncTypeCtrl->GetCount(); ++sync_it )
	{
		const SyncTypeClientData *stcd = dynamic_cast < const SyncTypeClientData * > 
		( mpDbSyncTypeCtrl->GetClientObject ( sync_it ) );
		if ( stcd->GetType() == (unsigned long)sync_type )
		{
			mpDbSyncTypeCtrl->SetSelection ( sync_it );
			break;
		}
	}

	mpDefaultDbCtrl->SetValue ( cfgh.GetValue ( cv::DefaultDatabase ) );

	long compr_level = 1;
	cfgh.GetValue ( cv::DatabaseCompressionLevel, compr_level );
	mpDbCompressionLevelCtrl->SetStringSelection ( wxString() << compr_level ); 
	
	mpDbAutoSaveCtrl->SetValue ( cfgh.IsEnabled ( cv::SaveDatabaseOnClose ) );
	mpDbAutoVacuumCtrl->SetValue ( cfgh.IsEnabled ( cv::AutoVacuumDatabase ) );

	// Load the "FreeDb" page settings.

	XRCCTRL ( *this, "ID_TextCtrl_ServerAddress", 
		wxTextCtrl )->SetValue ( cfgh.GetValue ( cv::FreeDbServerAddr ) );
	XRCCTRL ( *this, "ID_TextCtrl_Email", 
		wxTextCtrl )->SetValue ( cfgh.GetValue ( cv::FreeDbUserEmail ) );
	XRCCTRL ( *this, "ID_CheckBox_AutoSetFormat", 
		wxCheckBox )->SetValue ( cfgh.IsEnabled ( cv::FreeDbAutoSetFormatToCd ) );
}

void col::PreferencesDialog::SaveControlValues()
{
	typedef ConfigVariable cv;

	ConfigHandler &cfgh = ConfigHandler::Get();

	// Save the "General" page settings.

	for ( wxUint32 i = 0; i < mpGenSettingsCtrl->GetCount(); ++i )
	{
		cfgh.SetValue ( mGenSettingsItemData[i], mpGenSettingsCtrl->IsChecked(i) );
	}

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
		( langs->GetClientObject ( langs->GetSelection() ) );
	wxASSERT ( lang_data );

	cfgh.SetValue ( cv::Language, lang_data->GetLanguage() );

	// Save the "Database" page settings.

	const SyncTypeClientData *stcd = dynamic_cast < const SyncTypeClientData * > 
		( mpDbSyncTypeCtrl->GetClientObject ( mpDbSyncTypeCtrl->GetSelection() ) );
	wxASSERT ( stcd );

	cfgh.SetValue ( cv::DatabaseSyncType, stcd->GetType() );

	long lvl = -1;
	mpDbCompressionLevelCtrl->GetStringSelection().ToLong ( &lvl );
	cfgh.SetValue ( cv::DatabaseCompressionLevel, lvl != -1 ? lvl : 9 );
	
	cfgh.SetValue ( cv::DefaultDatabase, mpDefaultDbCtrl->GetValue() );
	cfgh.SetValue ( cv::SaveDatabaseOnClose, mpDbAutoSaveCtrl->IsChecked() );
	cfgh.SetValue ( cv::AutoVacuumDatabase, mpDbAutoVacuumCtrl->IsChecked() );

	// Save the "FreeDb" settings

	cfgh.SetValue ( cv::FreeDbAutoSetFormatToCd, XRCCTRL ( *this, "ID_CheckBox_AutoSetFormat", 
		wxCheckBox )->IsChecked() );
	cfgh.SetValue ( cv::FreeDbServerAddr, XRCCTRL ( *this, "ID_TextCtrl_ServerAddress", 
		wxTextCtrl )->GetValue() );
	cfgh.SetValue ( cv::FreeDbUserEmail, XRCCTRL ( *this, "ID_TextCtrl_Email", 
		wxTextCtrl )->GetValue() );
}

////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////

void col::PreferencesDialog::OnButtonBrowseDefaultDb ( wxCommandEvent & )
{
	wxFileDialog dlg ( this, _("Choose a file"), empty_string, 
		empty_string, _( "All Files (*.*)|*.*|COL Files (*.col)|*.col" ),
		wxFD_OPEN | wxFD_FILE_MUST_EXIST );

	if ( dlg.ShowModal() == wxID_OK )
	{
		mpDefaultDbCtrl->ChangeValue ( dlg.GetPath() );
	}
}

void col::PreferencesDialog::OnButtonResetDefaults ( wxCommandEvent & )
{
	if ( wxMessageBox (  _( "Are you sure that you wish to reset all "\
		"values to their defaults?" ) , _("Reset?"), 
		wxICON_QUESTION | wxYES_NO, this ) == wxYES )
	{
		ConfigHandler::Get().WriteDefaults ( true );
		LoadSettings();
	}
}

void col::PreferencesDialog::OnButtonOk ( wxCommandEvent &rEvent )
{
	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
		( langs->GetClientObject ( langs->GetSelection() ) );
	wxASSERT ( lang_data );

	long prev_lang = -1;
	ConfigHandler::Get().GetValue ( ConfigVariable::Language, prev_lang );
	wxASSERT ( prev_lang != -1 );

	if ( lang_data->GetLanguage() != prev_lang )
	{
		wxLogMessage ( _("Please restart the application "\
			"for the language settings to take effect.") );
	}
	SaveControlValues();
	rEvent.Skip();
}